package com.buba.livenuniappservernew.config;

import cn.hutool.json.JSONUtil;

import com.buba.livenuniappservernew.common.CommonResult;
import com.buba.livenuniappservernew.common.Const;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.Map;

/**
 * @author : md
 * @description : 登录拦截器
 * @date : 2023/8/14 15:51
 */
@Slf4j
@Configuration
public class LoginHandlerInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 目标方法执行之前
     * 登录检查写在这里，如果没有登录，就不执行目标方法
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(request.getMethod().equals("OPTIONS")){
            return true;
        }

//      获取进过拦截器的路径
        String requestURI = request.getRequestURI();
        //登录检查逻辑
        String token = request.getHeader("token");
        //token不存在，返回false
        if(StringUtil.isNullOrEmpty(token)){
            returnJson(response, this.return401());
            return false;
        }
        //通过token读取username
        String keyTokenUser = String.format("%s:%s", Const.TOKEN_USER, token);
        Object r = redisTemplate.opsForValue().get(keyTokenUser);
        //如果redis中的token不存在，返回false
        if(r==null){
            returnJson(response, this.return401());
            return false;
        }
//        if(StrUtil.isNotBlank(r.toString())){
//            returnJson(response, this.return401());
//            return false;
//        }
//        String mobile = r.toString();
//        request.setAttribute("uid", mobile);
//        response.setHeader("mobile", mobile);

//        Map<String,String> map=new HashMap<>();
//        map.put("mobile",mobile);

//        this.addHeader(request, map);

        return true;
    }

    /**
     * 目标方法执行完成以后
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 页面渲染以后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

    private String return401(){
        CommonResult result = CommonResult.error(401, "请重新登录");
        return JSONUtil.toJsonStr(result);
    }

    /**
     * 返回客户端数据
     */
    private void returnJson(HttpServletResponse response, String json) throws Exception{
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(json);

        } catch (IOException e) {
        } finally {
            if(writer != null) {
                writer.close();
            }
        }
    }
    private void addHeader(HttpServletRequest request, Map<String, String> headerMap) {
        if (headerMap==null||headerMap.isEmpty()){
            return;
        }

        Class<? extends HttpServletRequest> c=request.getClass();
        //System.out.println(c.getName());
//        System.out.println("request实现类="+c.getName());
        try{
            Field requestField=c.getDeclaredField("request");
            requestField.setAccessible(true);

            Object o=requestField.get(request);
            Field coyoteRequest=o.getClass().getDeclaredField("coyoteRequest");
            coyoteRequest.setAccessible(true);

            Object o2=coyoteRequest.get(o);
//            System.out.println("coyoteRequest实现类="+o2.getClass().getName());
            Field headers=o2.getClass().getDeclaredField("headers");
            headers.setAccessible(true);

            MimeHeaders mimeHeaders=(MimeHeaders) headers.get(o2);
            for (Map.Entry<String,String> entry:headerMap.entrySet()){
                mimeHeaders.removeHeader(entry.getKey());
                mimeHeaders.addValue(entry.getKey()).setString(entry.getValue());
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }

}
